﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

/// <summary>
/// 专门负责相机渲染，这种方法能让每个相机在未来更容易支持不同的渲染方法。例如一个渲染第一人称视图，一个渲染三维地图，或前向和延迟渲染的区别。
/// </summary>
public partial class CameraRender
{
    ScriptableRenderContext context;
    Camera camera;
    const string bufferName = "Render camera";
    CommandBuffer buffer = new CommandBuffer() { name = bufferName };
    static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");//
    static ShaderTagId[] legacyShaderTagIds =
    {
        new ShaderTagId("Always"),
        new ShaderTagId("ForwardBase"),
        new ShaderTagId("PrepassBase"),
        new ShaderTagId("Vertex"),
        new ShaderTagId("VertexLMRGBM"),
        new ShaderTagId("VertexLM")
    };
    public void Render(ScriptableRenderContext context, Camera camera)
    {
        this.context = context;
        this.camera = camera;
        PrepareBuffer();//更改缓冲区名称
        PrepareForSceneWindow();//cull前绘制Scene窗口中的UI
        if (!Cull())//如果裁剪失败，不渲染
            return;
        Setup();
        DrawVisibleGeometry();
        DrawUnsupportShaders();
        DrawGizmos();//所有物体绘制后绘制gizmos
        Submit();
    }

    void DrawVisibleGeometry()
    {
        var sortingSettings = new SortingSettings(camera)
        {
            criteria = SortingCriteria.CommonOpaque//设置排序规则
        };//确定是基于正交还是透视的排序
        var drawingSetting = new DrawingSettings(unlitShaderTagId, sortingSettings);//指定shader
        var filteringSetting = new FilteringSettings(RenderQueueRange.opaque);

        context.DrawSkybox(camera);//绘制天空盒

        sortingSettings.criteria = SortingCriteria.CommonTransparent;
        drawingSetting.sortingSettings = sortingSettings;
        filteringSetting.renderQueueRange = RenderQueueRange.all;//指定所有render queue都允许被绘制
        context.DrawRenderers(cullingResults, ref drawingSetting, ref filteringSetting);
    }
    static Material errorMat = new Material(Shader.Find("Hidden/InternalErrorShader"));
    //绘制不支持的shader
    void DrawUnsupportShaders()
    {
        var drawingSettings = new DrawingSettings(legacyShaderTagIds[0], new SortingSettings(camera));
        drawingSettings.overrideMaterial = errorMat;//指定错误材质进行绘制
        for (int i = 0; i < legacyShaderTagIds.Length; i++)
        {
            drawingSettings.SetShaderPassName(i, legacyShaderTagIds[i]);
        }
        var filteringSettings = FilteringSettings.defaultValue;
        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
    }

    //提交渲染，执行渲染
    void Submit()
    {
        buffer.EndSample(bufferName);//为profiler注入样本
        ExecuteBuffer();
        context.Submit();//提交
    }
    //渲染前设置
    void Setup()
    {
        context.SetupCameraProperties(camera);//设置相机相关的属性
        buffer.BeginSample(bufferName);//为profiler注入样本
        buffer.ClearRenderTarget(true, true, Color.clear);//清除帧缓冲
        ExecuteBuffer();
    }
    //执行command buffer
    void ExecuteBuffer()
    {
        context.ExecuteCommandBuffer(buffer);//执行command buffer
        buffer.Clear();
    }
    CullingResults cullingResults;
    bool Cull()
    {
        if(camera.TryGetCullingParameters(out ScriptableCullingParameters p))//获取裁剪参数
        {
            cullingResults = context.Cull(ref p);//相机裁剪
            return true;
        }
        return false;
    }
}
